const fs = require("fs")

// 读取文件
function readFileStream(filename) {
    return fs.readFileSync(filename, "utf-8", (err, data) => {
        if (err) {
            throw err
        } else {
            return data
        }
    })
}

// 读取当前目录, 获取样本文件名数组
let sampleFiles = []
fs.readdirSync("./").forEach((sampleFile => {
    if (sampleFile.endsWith(".gb")) {
        sampleFiles.push(sampleFile)
    }
}))

// 逐行读取生成的基因统计文件, 提取基因出现次数与样本数量相等的基因,
let geneList = []
readFileStream("./combined_gene_annotations.txt").split("\n").forEach((line) => {
    if (line && line.split(", ")[1]) {
        if (line.split(", ")[1].split(": ")[1] == sampleFiles.length) {
            geneList.push(line.split(", ")[0].split(": ")[1]);
        }
    }
})

// 从样本中获取整段基因序列
function getGeneSequenceFromSampleFile(filename, start, end) {
    let genes = []
    readFileStream(filename).split(/ORIGIN\s+/)[1].split("").forEach((letter) => {
        if (/[a-z]/.test(letter)) {
            genes.push(letter)
        }
    })
    return genes.slice(start - 1, end)
}

// 定位样本里要找的基因的起始和结束位置, 返回序列坐标, 以及是否有 complement
function locateGeneIndex(filename, gene) {
    let fileStreamBeforeORIGIN = readFileStream(filename).split(/ORIGIN\s+/)[0].split("\n")
    for (let [index, value] of fileStreamBeforeORIGIN.entries()) {
        if (value.includes(`gene="${gene}"`)) {
            return fileStreamBeforeORIGIN[index - 1].includes("complement") ?
                {
                    location: fileStreamBeforeORIGIN[index - 1].split("complement")[1].split("(")[1].split(")")[0].split(".."),
                    complement: true
                }
                :
                {
                    location: fileStreamBeforeORIGIN[index - 1].split(" ").slice(-1).join("").split(".."),
                    complement: false
                }
        }
    }
}

// 反转并替换
// a->t; t->a; c->g; g->c
function formatGeneSequence(data, complement) {
    let geneSequence = []
    if (complement) {
        geneSequence = data.reverse().map((e) => {
            switch (e) {
                case "a":
                    return e = "T"
                case "t":
                    return e = "A"
                case "c":
                    return e = "G"
                case "g":
                    return e = "C"
            }
        })
        return geneSequence.join("")
    } else {
        geneSequence = data.map((e) => {
            switch (e) {
                case "a":
                    return e = "A"
                case "t":
                    return e = "T"
                case "c":
                    return e = "C"
                case "g":
                    return e = "G"
            }
        })
        return geneSequence.join("")

    }
}

// mkdir fas
fs.mkdir("fas", (err) => {
    if (err) {
        console.log(err);
    }
})

// 写入文件
function writeFileStream(filename, data, sample, complement) {
    let filePath = `./fas/${filename}.fas`
    fs.appendFileSync(filePath, `>${sample}\n`)
    // 有 complement 则反转并替换后写入， 无则直接写入
    fs.appendFileSync(filePath, `${formatGeneSequence(data, complement)}\n`)
    console.log(`-> ${filePath}`);
}

for (let [indexOfGene, gene] of geneList.entries()) {
    for (let [indexOfSampleFile, sampleFile] of sampleFiles.entries()) {
        writeFileStream(gene,
            getGeneSequenceFromSampleFile(sampleFile, locateGeneIndex(sampleFile, gene).location[0], locateGeneIndex(sampleFile, gene).location[1]), sampleFile,
            locateGeneIndex(sampleFile, gene).complement)
    }
}